package no.ntnu.item.ttm4115.termproject.discussionagent;

import java.util.Enumeration;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeNode;

import com.thoughtworks.xstream.XStream;

import no.ntnu.item.ttm4115.termproject.StartUpRoleGA;
import no.tellu.common.javaframe.ActorAddress;
import no.tellu.common.javaframe.messages.RoleRequestMsg;
import no.tellu.common.actorframe.messages.RoleDeniedMsg;
import no.tellu.common.actorframe.messages.RoleConfirmMsg;
import no.ntnu.item.ttm4115.termproject.InformGroupDiscussion;
import no.ntnu.item.ttm4115.termproject.GetGroupMemberInfoToDiscussion;
import no.ntnu.item.ttm4115.termproject.discussionagent.gui.Discussion;
import no.ntnu.item.ttm4115.termproject.discussionagent.gui.DiscussionAgentGUI;
import no.ntnu.item.ttm4115.termproject.extrasagent.Group;
import no.ntnu.item.ttm4115.termproject.extrasagent.Player;
import no.ntnu.item.ttm4115.termproject.DistributeDiscussionEdit;
import no.ntnu.item.ttm4115.termproject.ForwardDiscussionUpdate;
import no.ntnu.item.ttm4115.termproject.DistributeDiscussionUpdate;
import no.ntnu.item.ttm4115.termproject.JoinDiscussion;
import no.ntnu.item.ttm4115.termproject.UpdateNewPlayerOnDiscussion;
import no.ntnu.item.ttm4115.termproject.ForwardDiscussionEdit;
import no.ntnu.item.ttm4115.termproject.GetMyMainFrame;
import no.ntnu.item.ttm4115.termproject.ReturnMainFrameFromPA;


public class DiscussionAgentActions extends Object {

	public static void sendRRToGroupAgent(StartUpRoleGA signal, DiscussionAgentSM asm){
	asm.playerName = signal.playerName;
	asm.groupName = signal.myGroupName;
	asm.mainFrame = signal.mainFrame;
	
	asm.sendMessage(new RoleRequestMsg(signal.myGroupName+"/discussionAgent", "DiscussionAgent"), signal.groupAdress);
	}
	
	public static void notAbleToCreateGADA(RoleDeniedMsg signal, DiscussionAgentSM asm){
	    // TODO edit action statements
	}

	public static void StartUpDiscussionAgent(RoleConfirmMsg signal, DiscussionAgentSM asm){
	    
		asm.myGroupAgent = signal.getSenderRole();
		asm.disGUI = new DiscussionAgentGUI(asm, asm.playerName, asm.myGroupAgent, asm.groupName, asm.mainFrame);
	    asm.sendMessage(new InformGroupDiscussion(asm.myGroupAgent,asm.playerName), signal.getSenderRole());
	}

	@SuppressWarnings("unchecked")
	public static void informGroupAboutStartedDiscussion(InformGroupDiscussion signal, DiscussionAgentSM asm){

		asm.playersInDiscussion.put(signal.playerName, signal.getSenderRole());
		asm.sendMessage(new GetGroupMemberInfoToDiscussion(asm.getMyActorAddress()),asm.getContext().getParentAddress());
	
	}
	@SuppressWarnings("unchecked")
	public static void UpdateDiscussionToAllPlayers(ForwardDiscussionUpdate signal, DiscussionAgentSM asm){
		
		XStream xstream = new XStream();
		xstream.setClassLoader(new Discussion().getClass().getClassLoader());
		xstream.alias("discussion", Discussion.class);
		xstream.setMode(XStream.XPATH_ABSOLUTE_REFERENCES);
		
		Object disc = (Object)xstream.fromXML(signal.xmlDisc);
		Object discFather = (Object)xstream.fromXML(signal.xmlDiscFather);
			
		
		Enumeration enume = ((DefaultMutableTreeNode)  asm.rootNode).breadthFirstEnumeration();
		DefaultMutableTreeNode dmtn = (DefaultMutableTreeNode) asm.rootNode;
		if (enume != null){
			while(enume.hasMoreElements()) {
				dmtn = (DefaultMutableTreeNode) enume.nextElement();
				System.out.println("Disc to be tested " + ((Discussion)dmtn.getUserObject()).getPostedDate() +
						" and disc father that has been received " + ((Discussion)discFather).getPostedDate());
				if( ((Discussion)dmtn.getUserObject()).getPostedDate().equalsIgnoreCase(
						((Discussion)discFather).getPostedDate())){
					break;
				}		
			}
		}
		DefaultMutableTreeNode node = new DefaultMutableTreeNode((Discussion)disc);
		System.out.println("Litt lengre opp");
		if (dmtn == null){
			System.out.println("We have a problem at updateDiscussioTreeCommentAddedByOthers from FWDiscussChgPlrToGrpActv");
		}
		else{
			dmtn.add((DefaultMutableTreeNode)node.clone());
		}
		
		
	   Iterator iterator = asm.playersInDiscussion.entrySet().iterator();
	    while(iterator.hasNext()){
	    	Map.Entry me = (Entry) iterator.next();
	    	
	    		asm.sendMessage(new DistributeDiscussionUpdate(signal.xmlDisc, signal.xmlDiscFather, signal.getSenderRole()), (ActorAddress)me.getValue());
	    	
	    	
	    	
	    }
	}
	
	public static void updateDiscussionGUI(DistributeDiscussionUpdate signal, DiscussionAgentSM asm){
		
		System.out.println("inni updateDiscussionGUI: ");
		System.out.println("XMLDISC i updateDiscussionGUI: "+signal.xmlDisc);
		System.out.println("XMLDISCFATHER i updateDiscussionGUI "+signal.xmlDiscFather);
		
		XStream xstream = new XStream();
		xstream.setClassLoader(new Discussion().getClass().getClassLoader());
		xstream.alias("discussion", Discussion.class);
		xstream.setMode(XStream.XPATH_ABSOLUTE_REFERENCES);
		
		Object disc = (Object)xstream.fromXML(signal.xmlDisc);
		Object discFather = (Object)xstream.fromXML(signal.xmlDiscFather);
		
		if(!asm.getMyActorAddress().equals(signal.contributorAddress)){
			asm.disGUI.updateDiscussioTreeCommentAddedByOthers((Discussion)(disc),(Discussion)discFather);
		}
		 
		
	}

	@SuppressWarnings("unchecked")
	public static void addNewPlayersToDiscussion(JoinDiscussion signal, DiscussionAgentSM asm){
	    asm.playersInDiscussion.put(signal.playerName, signal.myDiscussionAgentAddress);
		
	    XStream xstream = new XStream();
		xstream.alias("defaultmutabletreenode", DefaultMutableTreeNode.class);
		xstream.alias("enumeration", Enumeration.class);
		xstream.setMode(XStream.XPATH_ABSOLUTE_REFERENCES);
		
		Enumeration enume = ((DefaultMutableTreeNode)  asm.rootNode).breadthFirstEnumeration();
		DefaultMutableTreeNode dmtn = (DefaultMutableTreeNode) asm.rootNode;
		
		String xmlEnume = xstream.toXML(enume);
		String xmlDmtn = xstream.toXML(dmtn);
		
		String xmlRootNode = xstream.toXML(asm.rootNode);
		
		
	    asm.sendMessage(new UpdateNewPlayerOnDiscussion(signal.playerName, xmlRootNode, signal.myGroupName, xmlEnume, xmlDmtn), signal.myDiscussionAgentAddress);
	}

	public static void updateDiscussionEditGUI(DistributeDiscussionEdit signal, DiscussionAgentSM asm){
		if(!asm.getMyActorAddress().equals(signal.contributorAddress)){
			asm.disGUI.editDiscussioTreeCommentAddedByOthers((Discussion)(signal.disc),signal.newText);
		}
		
	}

	@SuppressWarnings("unchecked")
	public static void editDiscussionToAllPlayers(ForwardDiscussionEdit signal, DiscussionAgentSM asm){
	    Enumeration enume = ((DefaultMutableTreeNode)  asm.rootNode).breadthFirstEnumeration();
			DefaultMutableTreeNode dmtn = (DefaultMutableTreeNode) asm.rootNode;
			if (enume != null){
				while(enume.hasMoreElements()) {
					dmtn = (DefaultMutableTreeNode) enume.nextElement();
					System.out.println("Disc to be tested " + ((Discussion)dmtn.getUserObject()).getPostedDate() +
							" and disc father that has been received " + ((Discussion)signal.disc).getPostedDate());
					if( ((Discussion)dmtn.getUserObject()).getPostedDate().equalsIgnoreCase(
							((Discussion)signal.disc).getPostedDate())){
						break;
					}		
				}
			}
			if (dmtn == null){
				System.out.println("We have a problem at FWDiscussEditPlrToGrpActv");
			}
			else{
				((Discussion)dmtn.getUserObject()).setTopicText(signal.newText);
			}
			
			Iterator iterator = asm.playersInDiscussion.entrySet().iterator();
		    while(iterator.hasNext()){
		    	Map.Entry me = (Entry) iterator.next();
		    	
		    	asm.sendMessage(new DistributeDiscussionEdit(signal.disc, signal.newText, signal.getSenderRole()), (ActorAddress)me.getValue());
		    	
		    	
		    	
		    }
	}

	public static void publishStartedDiscussion(UpdateNewPlayerOnDiscussion signal, DiscussionAgentSM asm){

				
		asm.groupName = signal.groupName;
		asm.playerName = signal.myName;
		asm.tempSenderRole = signal.getSenderRole();
		asm.tempXmlRootNode = signal.xmlRootNode;
		asm.tempXMLEnume = signal.xmlEnume;
		asm.tempXMLDmtn = signal.xmlDmtn;
				
		asm.sendMessage(new GetMyMainFrame(), asm.getContext().getParentAddress());
	}

	public static void startupGUIDiscussionTab(ReturnMainFrameFromPA signal, DiscussionAgentSM asm){
		System.out.println("Arrived at return main frame");
		asm.mainFrame = signal.mainFrame;
		System.out.println("starting gui");
		asm.disGUI = new DiscussionAgentGUI(asm, asm.playerName, asm.tempSenderRole, asm.groupName, asm.mainFrame);
		
        XStream xstream = new XStream();
		xstream.alias("defaultmutabletreenode", DefaultMutableTreeNode.class);
		xstream.alias("enumeration", Enumeration.class);
		xstream.setMode(XStream.XPATH_ABSOLUTE_REFERENCES);
		//Object object = (Object)xstream.fromXML(asm.tempXmlRootNode);
		TreeNode rootNode= (TreeNode)xstream.fromXML(asm.tempXmlRootNode);
		
		Object o1 = (Object)xstream.fromXML(asm.tempXMLEnume);
		Object o2 = (Object)xstream.fromXML(asm.tempXMLDmtn);
		
		Enumeration enume = (Enumeration)o1;
		DefaultMutableTreeNode dmtn = (DefaultMutableTreeNode)o2;
		
		System.out.println("Enume"+asm.tempXMLEnume);
		System.out.println("Dmtn"+asm.tempXMLDmtn);
		//Enumeration enume = ((DefaultMutableTreeNode)  rootNode).breadthFirstEnumeration();
		//DefaultMutableTreeNode dmtn = (DefaultMutableTreeNode) enume.nextElement();
			if (enume != null){
				while(enume.hasMoreElements()) {
					System.out.println("Building a tree for this new guy");
					dmtn = (DefaultMutableTreeNode) enume.nextElement();
					asm.disGUI.updateDiscussioTreeCommentAddedByOthers( (Discussion) dmtn.getUserObject(),  (Discussion) ((DefaultMutableTreeNode)dmtn.getParent()).getUserObject()   );
				}
			}
	}



}
